//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.eResearch.Execution
{
    using System;
    using Microsoft.Research.DataLayer;
    using Microsoft.Research.eResearch.Common;
    using Microsoft.Research.eResearch.Common.Validation;
    using System.Reflection;
    using System.IO;

    /// <summary>
    /// This class contains the base logic for working with Job class.
    /// </summary>
    internal class JobBase
    {
        /// <summary>
        /// Initializes a new instance of the JobBase class.
        /// </summary>
        /// <param name="jobId">Id of the workflow job.</param>
        protected JobBase(Guid jobId, bool isLightWeightExecution)
        {
            // Validate arguments
            CustomValidator.AssertNotNull(jobId, "jobId");

            this.JobId = jobId;

            // Establish connection to registry.
            CreateRegistryConnection(isLightWeightExecution);

            // Load workflow job from registry.
            LoadJobFromRegistry();

            // Post condition
            CustomValidator.AssertRule<Job>(jb => jb.ActivityInstances.Count == 0, WorkflowJob, Messages.ZeroActivityInstanceError);
        }

        /// <summary>
        /// Gets the job id.
        /// </summary>
        protected Guid JobId { get; private set; }

        /// <summary>
        /// Gets the instance of the connection to registry.
        /// </summary>
        protected Connection RegistryConnection { get; private set; }

        /// <summary>
        /// Gets the instance of the workflow job.
        /// </summary>
        protected Job WorkflowJob { get; private set; }

        /// <summary>
        /// Deletes all the temporary Files Created.
        /// </summary>
        protected void CloseRegistryConnection()
        {
            ExceptionHandler.Handle(
            PolicyName.LoggingPolicy,
            () =>
            {
                // Close the registry Connection.
                if (RegistryConnection != null)
                {
                    RegistryConnection.Close();
                    RegistryConnection = null;
                }
            });
        }

        /// <summary>
        /// Open the Registry from config file whihc has Default Connection Set.
        /// </summary>
        private void CreateRegistryConnection(bool isLightWeightExecution)
        {
            SR_Connection.Init();
            ConnectionManager connectionManager = null;

            if (isLightWeightExecution)
            {
                Assembly me = Assembly.GetExecutingAssembly();
                string myPath = Path.GetDirectoryName(me.Location);

                //Put the alternate location
                ConnectionManager.AlternateProviderLocation = myPath;

                connectionManager = ConnectionManager.CreateCustom(
                    ConnectionManager.CancelBehavior.ThrowException,
                    Path.Combine(myPath, "ConnStore-Application.configSources"));
            }
            else
            {
                connectionManager = ConnectionManager.CreateForAgent(ConnectionManager.CancelBehavior.ThrowException, ConnectionManager.Agent.ExecutionService);
            }

            RegistryConnection = connectionManager.PickConnection(ConnectionManager.ConnectionUI.NeverShowUI);
            RegistryConnection.AutoSave = false;
        }

        /// <summary>
        /// Loads the job instance from registry for the current JobId. 
        /// </summary>
        private void LoadJobFromRegistry()
        {
            WorkflowJob = Job.Load(JobId, RegistryConnection);
        }
    }
}
